package com.itsu.mongodb.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.itsu.interfaces.entity.Friends;
import com.itsu.interfaces.entity.Publish;
import com.itsu.interfaces.entity.TimeLine;
import com.itsu.interfaces.entity.Video;
import com.itsu.interfaces.service.PublishService;
import com.itsu.pojo.constants.Constants;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;

import javax.swing.*;
import java.lang.invoke.ConstantCallSite;
import java.util.ArrayList;
import java.util.List;

@Service
public class PublishServiceImpl implements PublishService {

    @Autowired
    MongoTemplate mongoTemplate;

    @Override
    public ObjectId savePublish(Publish publish) {
        Publish save = mongoTemplate.save(publish);
        return save.getId();
    }

    @Override
    public Long countOfFriendQunzi(Long uid) {
        return mongoTemplate.count(new Query(), TimeLine.class, Constants.Timeline_DATABASE_NAME + uid);
    }

    @Override
    public Long countOfPublish() {
        return mongoTemplate.count(new Query(), Publish.class);
    }

    @Override
    public Publish findOneById(ObjectId publishId) {
        return mongoTemplate.findOne(Query.query(Criteria.where("id").is(publishId)), Publish.class);
    }

    @Override
    public List<Publish> findFriendsQunzi(Integer page, Integer pagesize, Long uid) {
        List<TimeLine> timeLineList = mongoTemplate.find(new Query()
                        .with(Sort.by(Sort.Order.desc("date")))
                        .with(PageRequest.of(page <= 1 ? 0 : page - 1, pagesize))
                , TimeLine.class, Constants.Timeline_DATABASE_NAME + uid);
        List<ObjectId> publishIdList = CollUtil.getFieldValues(timeLineList, "publishId", ObjectId.class);

        return mongoTemplate.find(Query.query(Criteria.where("id").in(publishIdList)), Publish.class);
    }

    @Override
    public List<Publish> findMovementsByPids(List<String> pisList) {
        return mongoTemplate.find(Query.query(Criteria.where("pid").in(pisList)), Publish.class);
    }

    @Override
    public List<Publish> randomMovements(Integer pagesize) {
        AggregationResults<Publish> aggregate = mongoTemplate.aggregate(Aggregation.newAggregation(Publish.class, Aggregation.sample(pagesize)), Publish.class);
        return aggregate.getMappedResults();
    }

    @Override
    public List<Publish> all() {
        Query query = new Query();
        query.with(Sort.by(Sort.Order.asc("user_id")));
        return mongoTemplate.find(query, Publish.class);
    }

    @Override
    public List<Publish> MessageLogs(String sub, Long uid, Long id, Long sd, Long ed) {
        Query query = new Query();

        if (ObjectUtil.isNotEmpty(uid)) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }

        if (ObjectUtil.isNotEmpty(id)) {
            query.addCriteria(Criteria.where("userId").is(id));
        }

        if (ObjectUtil.isNotEmpty(sd) && sd != -1 && ObjectUtil.isNotEmpty(ed) && ed != -1) {
            query.addCriteria(Criteria.where("created").gte(sd).lte(ed));
        }

        if ("desc".equals(sub)) {
            query.with(Sort.by(Sort.Order.desc("created")));
        } else if ("asc".equals(sub)) {
            query.with(Sort.by(Sort.Order.asc("created")));
        }
        return mongoTemplate.find(query, Publish.class);
    }
}
